"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const uuid_1 = require("src/utils/uuid");
const path = require("path");
const Nedb = require("nedb");
class NedbModel {
    constructor(id) {
        this.createTime = new Date().getTime();
        if (!id) {
            this._id = uuid_1.default();
        }
        else {
            this._id = id;
        }
    }
}
exports.NedbModel = NedbModel;
class NedbDao {
    constructor(dbDir) {
        this.compactRateForSave = 10000;
        this.actionCount = 0;
        const dbFile = path.join(dbDir, '/', this.constructor.name, '.db');
        this.nedb = new Nedb({
            filename: dbFile,
            autoload: true
        });
        this.nedb.loadDatabase();
        this.nedb.persistence.compactDatafile();
    }
    afterAction() {
        this.actionCount++;
        if (this.actionCount >= this.compactRateForSave) {
            this.nedb.persistence.compactDatafile();
            this.actionCount = 0;
        }
    }
    save(item) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                this.nedb.insert(item, (err) => {
                    if (err) {
                        reject(err);
                    }
                    else {
                        resolve(true);
                        this.afterAction();
                    }
                });
            });
        });
    }
    update(item) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                this.nedb.update({ _id: item._id }, item, {}, (err) => {
                    if (err) {
                        reject(err);
                    }
                    else {
                        resolve(true);
                        this.afterAction();
                    }
                });
            });
        });
    }
    findById(id, projection = {}) {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                this.nedb.findOne({ _id: id }, projection, (err, doc) => {
                    if (err) {
                        reject(err);
                    }
                    else {
                        resolve(doc);
                    }
                });
            });
        });
    }
}
exports.NedbDao = NedbDao;
